12 #define forit(it,l) for(it=(l).begin();it != (l).end(); it++)
13 #define forn(i,n) for(unsigned i= 0; i < ((unsigned)(n)); i++)
14 #define foreachin(it,s) for(typeof((s).begin()) it = ((s).begin()); it != ((s).end()); it++)
15 #define forsn(i,s,n) for(int i = (s); i < (n); i++)
16 void inline llenar_tabla(vector
<vector
<int> >& tabla
, const vector
<int>& frec
) {
19 //init de los intervalos de largo 1
23 //llenado de la tabla desde los mas chicos a los mas grandes
26 for (j
= 1; t
<= n
; j
++) {
27 for (i
= 0; i
+ (t
) - 1 < n
; i
++) {
29 if (frec
[tabla
[i
][k
]] > frec
[tabla
[i
+ (t_ant
)][k
]])
30 tabla
[i
][j
] = tabla
[i
][k
];
32 tabla
[i
][j
] = tabla
[i
+ (t_ant
)][k
];
40 static inline uint32_t log_2(const uint32_t x
) {
42 asm ( "\tbsr %1, %0\n"
50 void inline cargar_numeros(int cant_numeros
,vector
<int>& frec
,vector
<pair
<int,int> >& intervalostupla
,vector
<int>& intervaloindice
,int& intervalo
) {
53 int desde
,hasta
; //intervalo donde todos los elementos son iguales [ ]
54 int actual
; //elemento cuya frecuencia estoy construyendo
55 while (i
< cant_numeros
) {
63 if (actual
==numero
) { //si son iguales, incremento el hasta y su frecuencia
67 // si son distintos, se cerrĂ³ un intervalo, hay que empezar a armar otro
69 intervalostupla
[intervalo
] = pair
<int,int>(desde
,hasta
);
77 intervaloindice
[i
]=intervalo
;
83 //hack: el ultimo siempre quedaba sin agregar
84 intervalostupla
[intervalo
] = pair
<int,int>(desde
,hasta
);
87 void inline procesar_queries(const int queries
,const vector
<int>& frec
,const vector
<pair
<int,int> >& intervalostupla
,const vector
<int>& intervaloindice
,int& intervalo
) {
88 vector
<vector
<int> > tabla(intervalo
+1, vector
<int>(log_2(intervalo
+1)+1));
89 llenar_tabla(tabla
,frec
);
95 //desde y hasta son los intervalos extremos que hay que mirar.
96 //No necesariamente estan completos
97 desde
= intervaloindice
[x
-1];
98 hasta
= intervaloindice
[y
-1];
101 // Si esos indices son parte del mismo intervalo, la frecuencia es la distancia entre ellos.
105 //calculo por separado los intervalos que pueden ser truncos
106 int frec_i
= intervalostupla
[desde
].second
- x
+ 2;
107 int frec_j
= y
- intervalostupla
[hasta
].first
;
109 //el siguiente del desde y el anterior del hasta si estan completos
110 unsigned int intervalo_completo_i
= desde
+1;
111 unsigned int intervalo_completo_j
= hasta
-1;
113 res
= max(frec_i
,frec_j
);
114 if(intervalo_completo_i
<= intervalo_completo_j
){
115 unsigned int k
= log_2(intervalo_completo_j
- intervalo_completo_i
+ 1);
116 int aux
= frec
[tabla
[intervalo_completo_j
-(1<<k
)+1][k
]];
117 if (frec
[tabla
[intervalo_completo_i
][k
]] >= aux
)
118 res
= max(res
,frec
[tabla
[intervalo_completo_i
][k
]]);
129 int main(int argc
, char** argv
) {
132 open ("test.txt", O_RDONLY
);
134 //open ("myprog.out", O_WRONLY | O_CREAT, 0600);
137 int cant_numeros
,queries
;
138 scanf ("%d",&cant_numeros
);
141 while (cant_numeros
> 0) {
142 scanf ("%d",&queries
);
143 vector
<int> frec(cant_numeros
,1);//vector de frecuencias
144 int intervalo
=0;//cantidad de intervalos
145 vector
<int> intervaloindice(cant_numeros
); //dado un indice del arreglo, devuelve el numero de intervalo en el que esta
146 vector
<pair
<int,int> > intervalostupla(cant_numeros
); //dado un numero de intervalo, da su desde y hasta
148 cargar_numeros(cant_numeros
,frec
,intervalostupla
, intervaloindice
, intervalo
);
149 procesar_queries(queries
, frec
,intervalostupla
, intervaloindice
, intervalo
);
152 scanf ("%d",&cant_numeros
);
155 return (EXIT_SUCCESS
);